<template>
  <a-form ref="formRef" :model="form" :rules="rules" class="login-form-wrapper" layout="vertical">
    <div class="login-form-title">欢迎登录</div>
    <a-tabs v-model:active-key="tabActiveKey" animation size="mini">
      <a-tab-pane key="1" destroy-on-hide title="账号登录">
        <a-form-item field="username" hide-label validate-trigger="blur">
          <a-input v-model="form.username" autocomplete="username" placeholder="账号/邮箱">
            <template #prefix>
              <icon-user />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item field="password" hide-label validate-trigger="blur">
          <a-input-password v-model="form.password" allow-clear autocomplete="current-password" placeholder="请输入密码">
            <template #prefix>
              <icon-lock />
            </template>
          </a-input-password>
        </a-form-item>
        <a-checkbox v-model="form.rememberMe" checked="rememberMe"> 记住密码</a-checkbox>
      </a-tab-pane>
      <a-tab-pane key="2" destroy-on-hide title="手机号登录">
        <a-form-item field="phone" hide-label validate-trigger="blur">
          <a-input-group :style="{ width: '320px' }">
            <a-input v-model="form.phone" :max-length="11" allow-clear placeholder="请输入手机号" />
          </a-input-group>
        </a-form-item>
        <a-form-item field="code" hide-label>
          <a-input-group :style="{ width: '320px' }">
            <a-input v-model="form.code" allow-clear placeholder="请输入验证码"></a-input>
            <a-button :disabled="codeDisabled" style="width: 100px">
              {{ codeText }}
            </a-button>
          </a-input-group>
        </a-form-item>
      </a-tab-pane>
    </a-tabs>
    <a-button :loading="loading" long style="margin: 32px 0 6px" type="primary" @click.prevent="handleSubmitCaptcha">
      登录
    </a-button>
    <a-button class="login-form-register-btn" long type="text">注册</a-button>
    <a-divider orientation="center">更多方式</a-divider>
    <a-space :size="2" class="login-form-more" fill>
      <icon-alipay-circle style="color: #4b81ff" />
      <icon-wechat style="color: #38ad19" />
      <icon-lark-color />
      <icon-tiktok-color />
      <icon-github />
      <template #split>
        <a-divider direction="vertical" />
      </template>
    </a-space>
    <div class="login-form-actions">
      <a-checkbox v-model="form.agreement">我已阅读并同意</a-checkbox>
      <a-link>服务协议</a-link>
      <span>和</span>
      <a-link>隐私政策</a-link>
    </div>
    <div id="captcha-box" style="position: absolute; left: 2%" />
  </a-form>
</template>

<script lang="ts" setup>
import { useRouter } from "vue-router";
import { Message, Notification } from "@arco-design/web-vue";
import { IconCheckCircle } from "@arco-design/web-vue/es/icon";
import useLoading from "@/hooks/useLoading";
import { getCaptchaEnable } from "@/api/login";
import { to } from "await-to-js";
import useUserStore from "@/store/modules/user";
import { LoginData } from "@/api/types";

const userStore = useUserStore();
const { loading, setLoading } = useLoading();
const captchaConfig = {
  // 生成接口
  requestCaptchaDataUrl: import.meta.env.VITE_APP_BASE_API + "/getCaptcha",
  // 验证接口
  validCaptchaUrl: import.meta.env.VITE_APP_BASE_API + "/checkCaptcha",
  // 验证码绑定的div块
  bindEl: "#captcha-box",
  // 验证成功回调函数
  validSuccess: async (res: any, c: any, tac: any) => {
    // 销毁验证码服务
    await tac.destroyWindow();
    // 验证成功后进行登录操作
    await handleLogin(res.data.id);
  },
  // 验证失败的回调函数(可忽略，如果不自定义 validFail 方法时，会使用默认的)
  validFail: async (res: any, c: any, tac: any) => {
    // 验证失败后重新拉取验证码
    if (tac) {
      // 刷新验证码
      await tac.reloadCaptcha();
    } else {
      Message.error(res);
    }
  }
};

const captchaStyle = {
  // 按钮样式
  // btnUrl: "https://minio.tianai.cloud/public/captcha-btn/btn3.png",
  // 背景样式
  // bgUrl: "https://minio.tianai.cloud/public/captcha-btn/btn3-bg.jpg",
  // logo地址
  logoUrl: "https://www.asiainfo.com/include/images/logo.svg"
  // 滑动边框样式
  // moveTrackMaskBgColor: "#f7b645",
  // moveTrackMaskBorderColor: "#ef9c0d"
};

const captchaEnable = ref(false);
const router = useRouter();
const codeDisabled = ref(false);
const formRef = ref();
const redirect = ref(undefined);
const tabActiveKey = ref("1");
const codeText = ref("获取验证码");

const form = ref<LoginData>({
  // 用户名
  username: "",
  // 密码
  password: "",
  // 手机号
  phone: "",
  // 手机验证码
  code: "",
  // 滑块验证码
  id: "",
  // 是否同意
  agreement: false,
  // 记住模式
  rememberMe: false
} as LoginData);

const rules = {
  username: [{ required: true, message: "请输入账号/邮箱" }],
  code: [{ required: true, message: "请输入验证码" }],
  password: [
    { required: true, message: "请输入密码" },
    {
      // 密码格式：6-32位，包含大小写字母、数字、特殊字符(除空格)两种以上
      match: /^(?![\d]+$)(?![a-z]+$)(?![A-Z]+$)(?![~!@#$%^&*.]+$)[\da-zA-z~!@#$%^&*.]{6,32}$/,
      message: "密码格式不正确"
    }
  ],
  phone: [
    { required: true, message: "请输入手机号" },
    { length: 11, message: "手机号格式不正确" }
  ]
};

watch(
  () => router.currentRoute.value,
  (newRoute: any) => {
    redirect.value = newRoute.query && newRoute.query.redirect;
  },
  { immediate: true }
);

const handleSubmitCaptcha = async () => {
  if (!captchaEnable.value) {
    await handleLogin();
    return;
  }
  // 用户名密码模式
  if (tabActiveKey.value === "1") {
    formRef.value.validateField(["username", "password"]).then(async res => {
      if (res) {
        return;
      }
      if (!form.value.agreement) {
        return Message.info("请阅读并同意服务协议和隐私政策");
      }
      setLoading(true);
      try {
        await new TAC(captchaConfig, captchaStyle).init();
      } finally {
        setLoading(false);
      }
    });
  }
  // 手机验证码模式
  if (tabActiveKey.value === "2") {
    formRef.value.validateField(["phone", "code"]).then(async res => {
      if (res) {
        return;
      }
      if (!form.value.agreement) {
        return Message.info("请阅读并同意服务协议和隐私政策");
      }
      setLoading(true);
      try {
        await new TAC(captchaConfig, captchaStyle).init();
      } finally {
        setLoading(false);
      }
    });
  }
};

/**
 * 处理登陆
 * @param value 验证码ID 可为空
 */
const handleLogin = async (value: string | null = null) => {
  // 用户名密码登陆
  if (tabActiveKey.value === "1") {
    formRef.value.validateField(["username", "password"]).then(async res => {
      if (res) {
        return;
      }
      if (!form.value.agreement) {
        return Message.info("请阅读并同意服务协议和隐私政策");
      }
      // 如果勾选了记住模式
      if (form.value.rememberMe) {
        localStorage.setItem("username", String(form.value.username));
        localStorage.setItem("password", String(form.value.password));
        localStorage.setItem("rememberMe", String(form.value.rememberMe));
        localStorage.setItem("agreement", String(form.value.agreement));
      } else {
        // 否则移除
        localStorage.removeItem("username");
        localStorage.removeItem("password");
        localStorage.removeItem("rememberMe");
        localStorage.removeItem("agreement");
      }
      // 如果验证码不为null
      if (value) {
        form.value.id = value;
      }
      try {
        setLoading(true);
        const [err] = await to(userStore.login(form.value));
        if (!err) {
          await router.push({ path: redirect.value || "/" });
          const renderIcon = () => h(IconCheckCircle);
          Notification.success({
            title: "登录成功",
            content: "欢迎回来：" + useUserStore().name,
            closable: true,
            icon: renderIcon
          });
        }
      } finally {
        setLoading(false);
      }
    });
  }
  // 手机验证码登陆
  if (tabActiveKey.value === "2") {
    formRef.value.validateField(["phone", "code"]).then(res => {
      if (res) {
        return;
      }
      if (!form.value.agreement) {
        return Message.info("请阅读并同意服务协议和隐私政策");
      }
    });
  }
};

/**
 * 获取验证码状态
 */
const getCaptchaStatus = async () => {
  const res = await getCaptchaEnable();
  captchaEnable.value = res.data.captchaEnabled;
};

/**
 * 获取本地存储的账号密码
 */
const getLoginData = () => {
  const username = localStorage.getItem("username");
  const password = localStorage.getItem("password");
  const rememberMe = localStorage.getItem("rememberMe");
  const agreement = localStorage.getItem("agreement");
  form.value = {
    username: username == null ? String(form.value.username) : username,
    password: password == null ? String(form.value.password) : String(password),
    rememberMe: rememberMe == null ? false : Boolean(rememberMe),
    agreement: agreement == null ? false : Boolean(agreement)
  } as LoginData;
};

onMounted(() => {
  getCaptchaStatus();
  getLoginData();
});
</script>

<style lang="less" scoped>
.login-form {
  &-wrapper {
    width: 330px;
    padding: 24px 24px 12px;
    overflow: hidden;
    background-color: #fff;
    border: 1px solid var(--color-border-2);
    border-radius: var(--border-radius-large);
  }

  &-title {
    margin-bottom: 16px;
    font-size: 24px;
    font-weight: 500;
    line-height: 32px;
    color: var(--color-text-1);
  }

  &-actions {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    margin-top: 24px;
    margin-bottom: 6px;
  }

  &-register-btn {
    color: var(--color-text-3) !important;
  }

  &-more {
    justify-content: center;

    .arco-icon {
      font-size: 20px;
      cursor: pointer;
      transition: transform 0.2s ease;

      &:hover {
        transform: scale(1.3);
      }
    }
  }
}

:deep(.arco-tabs-content) {
  height: 155px;
}
</style>
